#include "Reverb.h"

#define filter_advance(p) if (--((p)->ptr) < (p)->buffer) (p)->ptr += (p)->sample_size

Reverb::Reverb(double sampleRate)
{
    this->sampleRate = sampleRate;
    double rate = this->sampleRate * (1 / 44100.0); // 补偿实际采样率

    for(int i=0; i<array_size(comb_lengths); i++)
    {
        filterComb[i].sample_size = (size_t)((double)comb_lengths[i] * rate + 0.5);
        filterComb[i].buffer = new float[filterComb[i].sample_size]();
        filterComb[i].ptr = filterComb[i].buffer;
        filterComb[i].store = 0.0f;
    }
    for(int i=0; i<array_size(allpass_lengths); i++)
    {
        filterAllpass[i].sample_size = (size_t)((double)allpass_lengths[i] * rate + 0.5);
        filterAllpass[i].buffer = new float[filterAllpass[i].sample_size]();
        filterAllpass[i].ptr = filterAllpass[i].buffer;
        filterAllpass[i].store = 0.0f;
    }
}

Reverb::~Reverb()
{
    for(int i=0; i<array_size(comb_lengths); i++)
    {
        delete[] filterComb[i].buffer;
    }
    for(int i=0; i<array_size(allpass_lengths); i++)
    {
        delete[] filterAllpass[i].buffer;
    }
}


void Reverb::setMix(float mixValue)
{
    if (mixValue < 0.0f) mixValue = 0.0f;
    if (mixValue > 100.0f) mixValue = 100.0f;
    mixValue /= 100.0f; // Convert to 0.0 to 1.0
    this->newMix = mixValue;
}

void Reverb::setTone(float toneValue)
{
    if (toneValue < 0.0f) toneValue = 0.0f;
    if (toneValue > 100.0f) toneValue = 100.0f;
    toneValue /= 100.0f; // Convert to 0.0 to 1.0
    this->newTone = toneValue;
}

void Reverb::setFeedback(float feedbackValue)
{
    if (feedbackValue < 0.0f) feedbackValue = 0.0f;
    if (feedbackValue > 100.0f) feedbackValue = 100.0f;
    feedbackValue /= 100.0f; // Convert to 0.0 to 1.0
    this->newFeedback = feedbackValue * 0.99f; // Prevent instability
}

void Reverb::setDamp(float dampValue)
{
    if (dampValue < 0.0f) dampValue = 0.0f;
    if (dampValue > 100.0f) dampValue = 100.0f;
    dampValue /= 100.0f; // Convert to 0.0 to 1.0
    this->newDamp = dampValue;
}

void Reverb::process(const float* input, float* output, size_t numSamples)
{
    for (size_t i = 0; i < numSamples; ++i)
    {
        float inSample = input[i];
        float outSample = 0.0f;

        mix = mix + (newMix - mix) * 0.001f;
        tone = tone + (newTone - tone) * 0.001f;
        feedback = feedback + (newFeedback - feedback) * 0.001f;
        damp = damp + (newDamp - damp) * 0.001f;

        // 通过梳状滤波器进行处理
        for (size_t j = 0; j < array_size(comb_lengths); ++j)
        {
            outSample += comb_process(&filterComb[j], inSample, feedback, damp);
        }
        outSample = outSample / (float)array_size(comb_lengths);

        // 通过全通滤波器进行处理
        for (size_t j = 0; j < array_size(allpass_lengths); ++j)
        {
            outSample = allpass_process(&filterAllpass[j], outSample);
        }

        // Mix dry and wet signals
        //output[i] = inSample * (1.0f - mix) + outSample * mix;
        outSample = lastOutput * (1.0f - tone) + outSample * tone; // Tone control
        lastOutput = outSample;
        output[i] = inSample + outSample * mix;
    }
}

float Reverb::comb_process(reverb_filter_t * p, float const input, float feedbackValue, float hf_damping)
{
    float output = *p->ptr;
    p->store = output + (p->store - output) * hf_damping;
    *p->ptr = input + p->store * feedbackValue;
    filter_advance(p);
    return output;
}

float Reverb::allpass_process(reverb_filter_t * p, float input)
{
    float output = *p->ptr;
    *p->ptr = input + output * 0.5f;
    filter_advance(p);
    return output - input;
}
